package com.financial.service.heemoney.service.impl;

import com.financial.service.heemoney.annotation.ValidateParam;
import com.financial.service.heemoney.constants.FinancialProregisterHeemoneylogEnumConstants;
import com.financial.service.heemoney.constants.FinancialProsubmitHeemoneylogEnumConstants;
import com.financial.service.heemoney.constants.FinancialReportHeemoneyEnumConstants;
import com.financial.service.heemoney.constants.FinancialSplitAccountHeemoneylogEnumConstants;
import com.financial.service.heemoney.convertor.HeemoneyProviderSubmitConvert;
import com.financial.service.heemoney.convertor.HeemoneyRegisterConvert;
import com.financial.service.heemoney.convertor.HeemoneyReportConvert;
import com.financial.service.heemoney.dao.FinancialProregisterHeemoneylogDao;
import com.financial.service.heemoney.dao.FinancialProsubmitHeemoneylogDao;
import com.financial.service.heemoney.dao.FinancialReportHeemoneyDao;
import com.financial.service.heemoney.domain.*;
import com.financial.service.heemoney.dto.HeemoneyConfigDTO;
import com.financial.service.heemoney.dto.businsess.HeemoneyProviderSubmitBusinessDTO;
import com.financial.service.heemoney.dto.commmon.HeemoneyProviderSubmitCommonDTO;
import com.financial.service.heemoney.dto.inparameter.*;
import com.financial.service.heemoney.dto.param.HeemoneyProviderSubmitParamDTO;
import com.financial.service.heemoney.service.*;
import com.financial.service.heemoney.utils.JsonUtils;
import com.financial.service.heemoney.utils.OkHttpUtils;
import com.financial.service.heemoney.utils.SignUtils;
import com.financial.service.heemoney.utils.apiresult.ApiResult;
import com.financial.service.heemoney.utils.apiresult.ApiResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;


@Service
public class FinancialReportHeemoneyServiceImpl implements FinancialReportHeemoneyService {
    @Autowired
    private FinancialReportHeemoneyDao financialReportHeemoneyDao;
    @Autowired
    private FinancialSplitAccountHeemoneyService financialSplitAccountHeemoneyService;
    @Autowired
    private FinancialRegisterHeemoneylogService financialRegisterHeemoneylogService;

    @Autowired
    private FinancialProsubmitHeemoneylogService financialProsubmitHeemoneylogService;

    @Autowired
    private FinancialSplitAccountHeemoneylogService FinancialSplitAccountHeemoneylogService;
    @Autowired
    private FinancialWxconfigHeemoneylogService financialWxconfigHeemoneylogService;
    @Autowired
    private FinancialProQueryHeemoneylogService FinancialProQueryHeemoneylogService;

    public static final Logger log = LoggerFactory.getLogger(FinancialPayHeemoneyServiceImpl.class);

    @Override
    @ValidateParam("com.financial.service.heemoney.dto.inparameter.HeemoneyReportInParamDTO")
    public ApiResult report(HeemoneyReportInParamDTO heemoneyReportInParamDTO, HeemoneySplitAccountInParamDTO heemoneySplitAccountInParamDTO) {

        log.info("金融中心汇收银商户统一报备接口入参：{}", JsonUtils.beanToJson(heemoneyReportInParamDTO));

        ApiResult apiResult = null;
        //子商户下的通道2
        String sub_mch_uid = "";
        Map<String, Object> resultMap = null;
        Map<String, Object> result = null;
        FinancialReportHeemoneyDO financialReportHeemoneyDO = new FinancialReportHeemoneyDO();

        //查询平台商户号状态：如果注册成功直接进行进件提交流程，否则重新注册商户
        HashMap<String, Object> reqMap = new HashMap<>();
        reqMap.put("platform_mch_uid", heemoneyReportInParamDTO.getParent_mch_uid());
        reqMap.put("is_delete", FinancialReportHeemoneyEnumConstants.ENUM_ISDELETE_UNDEL);
        List<FinancialReportHeemoneyDO> list = financialReportHeemoneyDao.list(reqMap);
        FinancialReportHeemoneyDO reportHeemoneyDO = list != null && list.size() > 0 ? list.get(0) : null;

        //注册状态非成功
        if (!reportHeemoneyDO.getReportState().equals(FinancialReportHeemoneyEnumConstants.ENUM_REPORTSTATE_REGISTERSUC)) {
            HeemoneyRegisterInParamDTO heemoneyRegisterInParamDTO = new HeemoneyRegisterInParamDTO();
            BeanUtils.copyProperties(heemoneyReportInParamDTO, heemoneyRegisterInParamDTO);
            //调用商户简要注册接口
            apiResult = financialRegisterHeemoneylogService.register(heemoneyRegisterInParamDTO);
            log.info("调用商户简要注册接口返回信息：{}", JsonUtils.objectToJson(apiResult));
            result = (Map<String, Object>) apiResult.getResult();
            //保存报备主业务信息
            financialReportHeemoneyDO.setAppIdAccount(result.get("app_id_account").toString());
            financialReportHeemoneyDO.setAppId(result.get("app_id").toString());
            financialReportHeemoneyDO.setAppIdSettle(result.get("app_id_settle").toString());
            financialReportHeemoneyDO.setGmtModified(new Date());
            financialReportHeemoneyDO.setGmtCreate(new Date());
            financialReportHeemoneyDO.setMchAccount(heemoneyReportInParamDTO.getMch_account());
            financialReportHeemoneyDO.setIsDelete(FinancialReportHeemoneyEnumConstants.ENUM_ISDELETE_UNDEL);
            financialReportHeemoneyDO.setProviderType(heemoneyReportInParamDTO.getProvider_type());
            financialReportHeemoneyDO.setPlatformNo(heemoneyReportInParamDTO.getPlatform_no());
            financialReportHeemoneyDO.setStoreNo(heemoneyReportInParamDTO.getStore_no());
            if (apiResult.getCode().equals("1")) {
                financialReportHeemoneyDO.setReportState(FinancialReportHeemoneyEnumConstants.ENUM_REPORTSTATE_REGISTERSUC);
                financialReportHeemoneyDO.setMchUid(result.get("merch_sub_uid").toString());
            } else {
                financialReportHeemoneyDO.setReportState(FinancialReportHeemoneyEnumConstants.ENUM_REPORTSTATE_REGISTERFAIL);
            }
            financialReportHeemoneyDao.save(financialReportHeemoneyDO);

            resultMap.put("result_msg", result.get("result_msg"));
            resultMap.put("mch_account", result.get("mch_account"));
            log.error("商户账户：{}，基础信息简要注册失败：{}，请重新注册！", result.get("mch_account"), result.get("result_msg"));
            return ApiResult.failure(resultMap);
        }
        //商户统一进件失败业务场景重新提交
        if (!reportHeemoneyDO.getReportState().equals(FinancialReportHeemoneyEnumConstants.ENUM_REPORTSTATE_SUBMITSUC)) {

            //获取商户简要注册生成的子商户号
            String mchUid = financialReportHeemoneyDO.getMchUid();
            HeemoneyProviderSubmitInParamDTO heemoneyProviderSubmitInParamDTO = new HeemoneyProviderSubmitInParamDTO();
            BeanUtils.copyProperties(heemoneyReportInParamDTO, heemoneyProviderSubmitInParamDTO);
            heemoneyProviderSubmitInParamDTO.setMch_uid(mchUid);
            apiResult = financialProsubmitHeemoneylogService.providerSubmit(heemoneyProviderSubmitInParamDTO);
            log.info("调用商户进件提交接口返回信息：{}", JsonUtils.objectToJson(apiResult));

            if (!apiResult.getCode().equals("1")) {
                financialReportHeemoneyDO.setReportState(FinancialReportHeemoneyEnumConstants.ENUM_REPORTSTATE_SUBMITFAIL);
                result = (Map<String, Object>) apiResult.getResult();
                resultMap.put("result_msg", result.get("result_msg"));
                resultMap.put("store_no", financialReportHeemoneyDO.getStoreNo());
                resultMap.put("mch_uid", mchUid);
                log.error("平台商户号：{}，统一进件提交失败：{}，请重新提交！", financialReportHeemoneyDO.getStoreNo(), result.get("result_msg"));
                return ApiResult.failure(resultMap);
            } else {
                financialReportHeemoneyDO.setSubMchId133(apiResult.get("sub_mch_uid").toString());
                financialReportHeemoneyDO.setReportState(FinancialReportHeemoneyEnumConstants.ENUM_REPORTSTATE_SUBMITSUC);
            }
            financialReportHeemoneyDao.update(financialReportHeemoneyDO);
            //进件提交成功后保存款分账账户请求明细
            FinancialSplitAccountHeemoneylogDO splitAccountHeemoneylogDO = new FinancialSplitAccountHeemoneylogDO();
            BeanUtils.copyProperties(heemoneySplitAccountInParamDTO, splitAccountHeemoneylogDO);
            splitAccountHeemoneylogDO.setGmtCreate(new Date());
            splitAccountHeemoneylogDO.setGmtModified(new Date());
            splitAccountHeemoneylogDO.setState(FinancialReportHeemoneyEnumConstants.ENUM_SPLITACCOUNT_WAIT);
            //保存请求参数快照
            FinancialSplitAccountHeemoneylogService.save(splitAccountHeemoneylogDO);
        }
        return ApiResult.success("商户进件已提交,请耐心等待审核通知");
    }


    @Override
    public ApiResult reportTask() {
        String sub_mch_id_133 = "";
        ApiResult apiResult = null;
        HashMap<String, Object> paramMap = new HashMap<>();
        //查询所有进件未审核商户
        paramMap.put("is_delete", FinancialReportHeemoneyEnumConstants.ENUM_ISDELETE_UNDEL);
        paramMap.put("report_state", FinancialReportHeemoneyEnumConstants.ENUM_REPORTSTATE_SUBMITSUC);
        List<FinancialReportHeemoneyDO> reportList = financialReportHeemoneyDao.list(paramMap);

        for (FinancialReportHeemoneyDO financialReportHeemoneyDO : reportList) {
            HeemoneyProviderQueryInParamDTO heemoneyProviderQueryInParamDTO = new HeemoneyProviderQueryInParamDTO();
            heemoneyProviderQueryInParamDTO.setMch_uid(financialReportHeemoneyDO.getMchUid());
            try {
                //调用进件查询接口
                apiResult = FinancialProQueryHeemoneylogService.providerQuery(heemoneyProviderQueryInParamDTO);
                //apiResult = providerQuery(heemoneyProviderQueryInParamDTO);
                if (!apiResult.getCode().equals("1")) {
                    String error_msg = apiResult.get("error_msg").toString();
                    log.error("商户号：{}，进件查询失败：{}", financialReportHeemoneyDO.getMchUid(), error_msg);
                    return ApiResult.failure("商户进件查询失败！");
                } else {
                    Map<String, Object> result = (Map<String, Object>) apiResult.getResult();
                    sub_mch_id_133 = result.get("sub_mch_id_133").toString();
                    //截取审核状态：LMFPAY100001742||1
                    String subMitStatus = sub_mch_id_133.substring(sub_mch_id_133.indexOf("||") + 1).trim();
                    if (subMitStatus.equals("-1")) {
                        return ApiResult.failure("进件提交审核失败,请联系业务人员处理!");
                    } else if (subMitStatus.equals("0")) {
                        return ApiResult.failure("进件提交审核中,请耐心等待！");
                    } else {
                        //进件审核状态成功，配置支付通道(根据商户号mch_uid及通道133子商户号（客商）sub_mch_id_133)
                        HeemoneyWxPayConfigInParamDTO heemoneyWxPayConfigInParamDTO = new HeemoneyWxPayConfigInParamDTO();
                        heemoneyWxPayConfigInParamDTO.setSub_mch_id_133(sub_mch_id_133);
                        heemoneyWxPayConfigInParamDTO.setMch_uid(financialReportHeemoneyDO.getMchUid());
                        apiResult = financialWxconfigHeemoneylogService.wxconfig(heemoneyWxPayConfigInParamDTO);
                        if (!apiResult.getCode().equals("1")) {
                            log.error("商户号：{},定时处理微信支付通道配置失败！", financialReportHeemoneyDO.getMchUid());
                            return ApiResult.failure("微信支付通道配置失败！");
                        }
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
                log.error("商户配置微信支付通道失败：{}", e.getMessage());
            }

            //判断进件商户行政类型，5 个体工商户，4 企业，6 个人  企业 若是企业必须先开通付款分账账户
            // if(){}
        }

        return ApiResult.success(apiResult);

    }

    @Override
    public ApiResult asynReport(String asynParam) {

        log.info("金融中心汇收银商户进件提交异步接口回执参数：{}", JsonUtils.beanToJson(asynParam));
        //验证签名信息
        ApiResult apiResult = null;
        FinancialReportHeemoneyDO reportHeemoneyDO = null;
        //封装返回值
        Map<String, Object> resultMap = new HashMap<>();
        try {

            boolean b = SignUtils.verifySign(asynParam);
            log.info("汇收银商户进件提交异步回执签名验证结果：{}", b);
            if (b == true) {
                //验证签名成功获取业务参数
                Map<String, Object> chanageMap = JsonUtils.jsonToMap(asynParam);
                String sub_mch_id_133 = chanageMap.get("sub_mch_id_133").toString();
                String mch_id = chanageMap.get("mch_id").toString();
                //截取进件审核状态：LMFPAY100001742||1
                String subMitStatus = sub_mch_id_133.substring(sub_mch_id_133.indexOf("||") + 1).trim();
                if (subMitStatus.equals("-1")) {
                    return ApiResult.failure("进件提交审核失败,请联系业务人员处理!");
                } else if (subMitStatus.equals("0")) {
                    return ApiResult.failure("进件提交审核中,请耐心等待！");
                } else {
                    //进件审核状态成功，配置支付通道(根据商户号mch_uid及通道133子商户号（客商）sub_mch_id_133)
                    HeemoneyWxPayConfigInParamDTO heemoneyWxPayConfigInParamDTO = new HeemoneyWxPayConfigInParamDTO();
                    heemoneyWxPayConfigInParamDTO.setSub_mch_id_133(sub_mch_id_133);
                    heemoneyWxPayConfigInParamDTO.setMch_uid(mch_id);
                    apiResult = financialWxconfigHeemoneylogService.wxconfig(heemoneyWxPayConfigInParamDTO);
                    log.info("汇收银商户配置支付通道接口回执：{}", apiResult);

                    //根据商户id获取该条报备主信息
                    Map<String, Object> strMap = new HashMap<>();
                    strMap.put("mch_id", mch_id);
                    strMap.put("report_state", FinancialReportHeemoneyEnumConstants.ENUM_REPORTSTATE_SUBMITSUC);
                    strMap.put("is_delete", FinancialProsubmitHeemoneylogEnumConstants.ENUM_ISDELETE_UNDEL);
                    List<FinancialReportHeemoneyDO> listDo = financialReportHeemoneyDao.list(strMap);
                    reportHeemoneyDO = listDo != null && listDo.size() > 0 ? listDo.get(0) : null;
                    //修改报备主业务状态
                    if (!apiResult.getCode().equals("1")) {
                        log.error("汇收银第三方商户号：{},微信支付通道配置失败！", mch_id);
                        reportHeemoneyDO.setReportState(FinancialReportHeemoneyEnumConstants.ENUM_REPORTCONFIG_FAIL);
                        return ApiResult.failure("微信支付通道配置失败！");
                    }
                    reportHeemoneyDO.setReportState(FinancialReportHeemoneyEnumConstants.ENUM_REPORTCONFIG_SUC);
                    financialReportHeemoneyDao.update(reportHeemoneyDO);

                    //根据商户id获取付款账户信息
                    Map<String, Object> objMap = new HashMap<>();
                    objMap.put("mch_id", mch_id);
                    objMap.put("report_state", FinancialReportHeemoneyEnumConstants.ENUM_SPLITACCOUNT_WAIT);
                    objMap.put("is_delete", FinancialProsubmitHeemoneylogEnumConstants.ENUM_ISDELETE_UNDEL);
                    List<FinancialSplitAccountHeemoneylogDO> list = FinancialSplitAccountHeemoneylogService.list(objMap);
                    FinancialSplitAccountHeemoneylogDO logDO = list != null && list.size() > 0 ? list.get(0) : null;
                    HeemoneySplitAccountInParamDTO splitAccountInParamDTO = new HeemoneySplitAccountInParamDTO();
                    BeanUtils.copyProperties(logDO, splitAccountInParamDTO);
                    //调用开通付款分账账户
                    Map<String, Object> returnMap = financialSplitAccountHeemoneyService.splitAccount(splitAccountInParamDTO);
                    log.info("报备主业务流程调用付款分账账户接口回执：{}", JsonUtils.objectToJson(returnMap));

                    String result_code = returnMap.get("result_code").toString();

                    resultMap.put("store_no", reportHeemoneyDO.getStoreNo());
                    resultMap.put("mch_id", mch_id);

                    if (!result_code.equals("SUCCESS")) {
                        log.error("平台商户号：{}开通付款结算账户失败！", reportHeemoneyDO.getStoreNo());
                        //更改报备主业务状态为报备失败
                        String error_msg = returnMap.get("error_msg").toString();
                        reportHeemoneyDO.setReportState(FinancialReportHeemoneyEnumConstants.ENUM_REPORTSTATE_FAIL);
                        resultMap.put("return_msg", error_msg);
                        return ApiResult.failure(resultMap);
                    }
                    reportHeemoneyDO.setReportState(FinancialReportHeemoneyEnumConstants.ENUM_REPORTSTATE_SUC);
                    financialReportHeemoneyDao.update(reportHeemoneyDO);
                    //拼接返回数据结构
                    String return_msg = returnMap.get("return_msg").toString();
                    resultMap.put("return_msg", return_msg);
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("汇收银商户进件异步回执接口处理商户报备失败！平台商户号为：{}", reportHeemoneyDO.getStoreNo());
        }

        return ApiResult.success(resultMap);
    }


    @Override
    public FinancialReportHeemoneyDO get(Integer id) {
        return financialReportHeemoneyDao.get(id);
    }

    @Override
    public List<FinancialReportHeemoneyDO> list(Map<String, Object> map) {
        return financialReportHeemoneyDao.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        return financialReportHeemoneyDao.count(map);
    }

    @Override
    public int save(FinancialReportHeemoneyDO financialReportHeemoney) {
        return financialReportHeemoneyDao.save(financialReportHeemoney);
    }

    @Override
    public int update(FinancialReportHeemoneyDO financialReportHeemoney) {
        return financialReportHeemoneyDao.update(financialReportHeemoney);
    }

    @Override
    public int remove(Integer id) {
        return financialReportHeemoneyDao.remove(id);
    }

    @Override
    public int batchRemove(Integer[] ids) {
        return financialReportHeemoneyDao.batchRemove(ids);
    }


}
